package com.integrate.multiple.sources.conf.datasource;


import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Properties;

/**
 * @author 刘志强
 * @date 2020/11/27 14:02
 * @MapperScan(basePackages = {"com.integrate.multiple.sources.mapper.producer"}, sqlSessionFactoryRef = "producerSqlSessionFactory")
 * com.integrate.multiple.sources.mapper.producer 声明数据源生效目录
 */
@Configuration
@MapperScan(basePackages = {"com.integrate.multiple.sources.mapper.producer"}, sqlSessionFactoryRef = "producerSqlSessionFactory")
public class ProducerDataSourceConfiguration {

    /**
     * 加载 producer库 配置
     * @return
     */
    @Bean("producerDatasourceModel")
    @ConfigurationProperties(prefix = "spring.datasource.producer")
    public DatasourceModel producerDatasourceModel() {
        DatasourceModel datasourceModel = new DatasourceModel();
        datasourceModel.setType(DruidDataSource.class);
        return datasourceModel;
    }

    /**
     * 配置数据源producer
     *
     * @return
     */
    @Bean(name = "producerDataSource")
    public DataSource producerDataSource(
            @Qualifier("poolProperties") Properties poolProperties,
            @Qualifier("producerDatasourceModel") DatasourceModel producerDatasourceModel) throws SQLException {
        // 创建DruidDataSource
        DruidDataSource druidDataSource = (DruidDataSource) DataSourceBuilder.create()
                // 设置数据源类型
                .type(producerDatasourceModel.getType())
                .driverClassName(producerDatasourceModel.getDriverClassName())
                .url(producerDatasourceModel.getUrl())
                .username(producerDatasourceModel.getUserName())
                .password(producerDatasourceModel.getPassword())
                .build();
        // 加载链接池信息
        druidDataSource.configFromPropety(poolProperties);
        // 数据源初始化
        druidDataSource.init();
        return druidDataSource;
    }

    /**
     * producer数据库的会话工厂
     *
     * @param producerDataSource
     * @param properties
     * @param resourceLoader
     * @return
     * @throws Exception
     */
    @Bean(name = "producerSqlSessionFactory")
    public SqlSessionFactory producerSqlSessionFactory(
            @Qualifier("producerDataSource") DataSource producerDataSource,
            @Qualifier("mybatisData") MybatisProperties properties,
            ResourceLoader resourceLoader) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        // 设置数据源
        bean.setDataSource(producerDataSource);
        // 设置类型包
        bean.setTypeAliasesPackage(properties.getTypeAliasesPackage());
        // 设置mybatis配置文件
        bean.setConfigLocation(resourceLoader.getResource(properties.getConfigLocation()));
        // 设置Mapper.xml位置
        bean.setMapperLocations(properties.resolveMapperLocations());
        return bean.getObject();
    }

    /**
     * producer数据库的会话模板
     *
     * @param producerSqlSessionFactory
     * @return
     */
    @Bean(name = "producerSqlSessionTemplate")
    public SqlSessionTemplate producerSqlSessionTemplate(@Qualifier("producerSqlSessionFactory") SqlSessionFactory producerSqlSessionFactory) {
        return new SqlSessionTemplate(producerSqlSessionFactory);
    }

    /**
     * producer数据库的事务
     *
     * @param producerDataSource
     * @return
     */
    @Bean(name = "producerTransactionManager")
    public DataSourceTransactionManager producerTransactionManager(@Qualifier("producerDataSource") DataSource producerDataSource) {
        return new DataSourceTransactionManager(producerDataSource);
    }

}
